import json
import os.path
import copy
from Utility import *

# ===CODE===

# 【注意】db文件格式
# 参考develop.md的第4.2节

class SimpleMakeDB:
    '''这个类用于保存所有构建信息
    【注意】file_name都是solution_dir内的相对路径'''
    def __init__(self):
        self.empty_db = {
            'global_md5' : '',
            'proj_md5' : {},
            'file_mod_time' : {},  # {file_name : mtime}
            'file_dep': {},
            'proj_success' : {},
            'file_success' : {}
        }
        self.db = copy.deepcopy(self.empty_db)
        self.history = copy.deepcopy(self.empty_db)
        self.db_file_path = None
        self.proj_files = {} # {proj_name : set()}

    def load(self, smake_out_dir:str) -> None:
        '''加载db文件，作为history'''
        self.db_file_path = path_join(smake_out_dir, '.db.json')
        if os.path.exists(self.db_file_path) == False:
            # 不存在就使用空db
            return
        with open(self.db_file_path) as f:
            content = f.read()
            self.history = json.loads(content)

    def save(self):
        '''把db中的内容覆盖写入db文件中'''
        content = json.dumps(self.db, indent=4)
        with open(self.db_file_path, 'w') as f:
            f.write(content)

    def set_global_conf_md5(self, val:str):
        self.db['global_md5'] = val

    def get_global_conf_md5(self):
        return self.db['global_md5']

    def get_history_global_conf_md5(self):
        return self.history['global_md5']

    def set_proj_conf_md5(self, proj_name:str, val:str):
        self.db['proj_md5'][proj_name] = val

    def get_proj_conf_md5(self, proj_name):
        '''成功返回md5，否则返回空字符串'''
        if proj_name not in self.db['proj_md5']:
            return ''
        return self.db['proj_md5'][proj_name]

    def get_history_proj_conf_md5(self, proj_name):
        '''成功返回md5，否则返回空字符串'''
        if proj_name not in self.history['proj_md5']:
            return ''
        return self.history['proj_md5'][proj_name]

    def set_proj_success(self, proj_name, is_s:bool):
        self.db['proj_success'][proj_name] = is_s

    def get_history_proj_success(self, proj_name):
        '''成功返回相应的值，否则返回false'''
        if proj_name not in self.history['proj_success']:
            return False
        return self.history['proj_success'][proj_name]

    def set_file_success(self, file_name, is_s:bool):
        self.db['file_success'][file_name] = is_s

    def set_file_rely(self, file_name:str, deps:list):
        self.db['file_dep'][file_name] = deps

    def set_file_rely_by_history(self, file_name:str):
        '''用历史值设置当前文件的依赖。用于不需要重新分析的情况。'''
        if file_name not in self.history['file_dep']:
            self.db['file_dep'][file_name] = []
        else:
            self.db['file_dep'][file_name] = self.history['file_dep'][file_name]

    def get_file_rely(self, file_name:str):
        '''如果有相应的记录，则返回该记录，否则返回空'''
        if file_name in self.db['file_dep']:
            return self.db['file_dep'][file_name]
        else:
            return []

    def get_history_file_success(self, file_name):
        '''成功返回相应的值，否则返回false'''
        if file_name not in self.history['file_success']:
            return False
        return self.history['file_success'][file_name]

    def set_file_mtimes(self, proj_name, file_mtimes:dict) -> None:
        '''设置项目内文件的mtime，同时记录项目拥有的文件'''
        self.db['file_mod_time'].update(file_mtimes)
        if proj_name not in self.proj_files:
            self.proj_files[proj_name] = set()
        self.proj_files[proj_name].update(file_mtimes.keys())

    def get_file_mtime(self, file_name) -> float:
        '''获取定文件的mtime，文件不存在时返回0.0'''
        if file_name in self.db['file_mod_time']:
            return self.db['file_mod_time'][file_name]
        # 当前db不应该存在key不存在的情况
        return 0.0

    def get_history_file_mtimes(self, file_name) -> float:
        '''获取历史记录中，项目中指定文件的mtime，项目或文件不存在时返回0.0'''
        if file_name in self.history['file_mod_time']:
            return self.history['file_mod_time'][file_name]
        return 0.0

    def get_proj_file_mtimes(self, proj_name) -> dict:
        '''获取项目的所有文件的mtime，项目不存在时返回{}'''
        if proj_name in self.db['file_mod_time']:
            return self.db['file_mod_time'][proj_name]
        return {}

    def get_history_proj_file_mtimes(self, proj_name) -> dict:
        '''获取历史记录中，项目的所有文件的mtime，项目不存在时返回{}'''
        if proj_name in self.history['file_mod_time']:
            return self.history['file_mod_time'][proj_name]
        return {}
    
    def is_src_file_count_changed(self, proj_name) -> bool:
        '''根据file_dep的keys，来判断src文件个数是否有增减'''
        if proj_name in self.db['file_dep']:
            if proj_name in self.history['file_dep']:
                return len(self.db['file_dep'][proj_name]) != len(self.history['file_dep'][proj_name])
        return True

g_db = SimpleMakeDB()
